package com.zenithmind.library.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.library.pojo.domain.Book;
import com.zenithmind.library.pojo.query.BookQuery;
import com.zenithmind.library.pojo.vo.BookDetailVO;
import com.zenithmind.library.pojo.vo.BookVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDate;
import java.util.List;

/**
 * 图书Mapper接口
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Mapper
public interface BookMapper extends BaseMapper<Book> {

    /**
     * 分页查询图书
     * 
     * @param page 分页参数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BookVO> selectBookPage(Page<BookVO> page, @Param("query") BookQuery query);

    /**
     * 根据ID查询图书详情
     * 
     * @param id 图书ID
     * @return 图书详情
     */
    BookDetailVO selectBookDetailById(@Param("id") String id);

    /**
     * 根据ISBN查询图书
     * 
     * @param isbn ISBN
     * @return 图书信息
     */
    BookVO selectBookByIsbn(@Param("isbn") String isbn);

    /**
     * 根据分类ID查询图书
     * 
     * @param page 分页参数
     * @param categoryId 分类ID
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BookVO> selectBooksByCategory(Page<BookVO> page, 
                                       @Param("categoryId") String categoryId, 
                                       @Param("query") BookQuery query);

    /**
     * 根据作者ID查询图书
     * 
     * @param page 分页参数
     * @param authorId 作者ID
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BookVO> selectBooksByAuthor(Page<BookVO> page, 
                                     @Param("authorId") String authorId, 
                                     @Param("query") BookQuery query);

    /**
     * 根据出版社ID查询图书
     * 
     * @param page 分页参数
     * @param publisherId 出版社ID
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BookVO> selectBooksByPublisher(Page<BookVO> page, 
                                        @Param("publisherId") String publisherId, 
                                        @Param("query") BookQuery query);

    /**
     * 搜索图书
     * 
     * @param page 分页参数
     * @param keyword 关键词
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BookVO> searchBooks(Page<BookVO> page, 
                             @Param("keyword") String keyword, 
                             @Param("query") BookQuery query);

    /**
     * 获取推荐图书
     * 
     * @param page 分页参数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BookVO> selectRecommendedBooks(Page<BookVO> page, @Param("query") BookQuery query);

    /**
     * 获取新书
     * 
     * @param page 分页参数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BookVO> selectNewBooks(Page<BookVO> page, @Param("query") BookQuery query);

    /**
     * 获取热门图书
     * 
     * @param page 分页参数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<BookVO> selectPopularBooks(Page<BookVO> page, @Param("query") BookQuery query);

    /**
     * 更新图书库存
     * 
     * @param bookId 图书ID
     * @param totalCopies 总库存
     * @param availableCopies 可借阅库存
     * @return 更新行数
     */
    int updateBookStock(@Param("bookId") String bookId, 
                       @Param("totalCopies") Integer totalCopies, 
                       @Param("availableCopies") Integer availableCopies);

    /**
     * 增加图书借阅次数
     * 
     * @param bookId 图书ID
     * @return 更新行数
     */
    int incrementBorrowCount(@Param("bookId") String bookId);

    /**
     * 减少可借阅数量
     * 
     * @param bookId 图书ID
     * @return 更新行数
     */
    int decrementAvailableCopies(@Param("bookId") String bookId);

    /**
     * 增加可借阅数量
     * 
     * @param bookId 图书ID
     * @return 更新行数
     */
    int incrementAvailableCopies(@Param("bookId") String bookId);

    /**
     * 增加已借阅数量
     * 
     * @param bookId 图书ID
     * @return 更新行数
     */
    int incrementBorrowedCopies(@Param("bookId") String bookId);

    /**
     * 减少已借阅数量
     * 
     * @param bookId 图书ID
     * @return 更新行数
     */
    int decrementBorrowedCopies(@Param("bookId") String bookId);

    /**
     * 更新图书评分
     * 
     * @param bookId 图书ID
     * @param rating 评分
     * @param reviewCount 评价数量
     * @return 更新行数
     */
    int updateBookRating(@Param("bookId") String bookId, 
                        @Param("rating") Double rating, 
                        @Param("reviewCount") Integer reviewCount);

    /**
     * 获取相关推荐图书
     * 
     * @param bookId 图书ID
     * @param limit 限制数量
     * @return 推荐图书列表
     */
    List<BookVO> selectRelatedBooks(@Param("bookId") String bookId, @Param("limit") Integer limit);

    /**
     * 统计图书数量
     * 
     * @param query 查询条件
     * @return 图书数量
     */
    Long countBooks(@Param("query") BookQuery query);

    /**
     * 统计分类下的图书数量
     * 
     * @param categoryId 分类ID
     * @return 图书数量
     */
    Long countBooksByCategory(@Param("categoryId") String categoryId);

    /**
     * 统计作者的图书数量
     * 
     * @param authorId 作者ID
     * @return 图书数量
     */
    Long countBooksByAuthor(@Param("authorId") String authorId);

    /**
     * 统计出版社的图书数量
     * 
     * @param publisherId 出版社ID
     * @return 图书数量
     */
    Long countBooksByPublisher(@Param("publisherId") String publisherId);

    /**
     * 获取热门搜索关键词
     * 
     * @param limit 限制数量
     * @return 关键词列表
     */
    List<String> selectHotSearchKeywords(@Param("limit") Integer limit);

    /**
     * 获取图书借阅排行榜
     * 
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param limit 限制数量
     * @return 图书列表
     */
    List<BookVO> selectBorrowRanking(@Param("startDate") LocalDate startDate, 
                                    @Param("endDate") LocalDate endDate, 
                                    @Param("limit") Integer limit);

    /**
     * 批量更新图书状态
     * 
     * @param ids 图书ID列表
     * @param status 状态
     * @return 更新行数
     */
    int batchUpdateBookStatus(@Param("ids") List<String> ids, @Param("status") Integer status);

    /**
     * 批量更新推荐状态
     * 
     * @param ids 图书ID列表
     * @param isRecommended 是否推荐
     * @return 更新行数
     */
    int batchUpdateRecommendStatus(@Param("ids") List<String> ids, @Param("isRecommended") Integer isRecommended);
}
